// ignore_for_file: library_private_types_in_public_api

import 'dart:async';
import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_smart_heating/ui/ui.dart';
import 'package:get/get.dart';

import 'package:video_player/video_player.dart';
import 'package:visibility_detector/visibility_detector.dart';
import 'package:provider/provider.dart';

class UiVideoData with ChangeNotifier {
  double? progress;
  String? title;
  bool isFullScreen = false;
  bool isError = false;
  bool showControl = true;
  bool isPlaying = false;
  bool isCompleted = false;
  bool get showPlayButton {
    return !controller.value.isPlaying && !controller.value.isBuffering;
  }

  late VideoPlayerController controller;

  notify() {
    notifyListeners();
  }
}

class UiVideo extends StatefulWidget {
  const UiVideo({
    super.key,
    required this.url,
    this.autoPlay = false,
    this.loop = false,
    this.isLive = false,
    this.title,
    this.onReady,
  });
  final String url;
  final bool autoPlay;
  final bool loop;
  final String? title;
  final bool isLive;
  final Function(double)? onReady;

  @override
  State<UiVideo> createState() => _UiVideoState();
}

class _UiVideoState extends State<UiVideo> {
  bool isPlayingBeforeLeave = false; //离开页面时候在播放

  UiVideoData data = UiVideoData();
  double? get progress {
    if (data.controller.value.duration.inMilliseconds == 0) {
      return null;
    }
    return data.controller.value.position.inMicroseconds /
        data.controller.value.duration.inMicroseconds;
  }

  @override
  void initState() {
    super.initState();
    data.controller = VideoPlayerController.networkUrl(
      Uri.parse(widget.url),
    )..initialize().then((_) {
        data.isError = false;

        /// 循环播放
        data.controller.setLooping(widget.loop);

        /// 自动播放
        if (widget.autoPlay) {
          data.controller.play();
        }
        widget.onReady?.call(data.controller.value.aspectRatio);
      }).catchError((error) {
        data.isError = true;
        data.notify();
      });
    data.controller.addListener(() {
      if (mounted) {
        data.progress = progress;
        data.title = widget.title;

        data.isPlaying = data.controller.value.isPlaying;
        data.isCompleted = data.controller.value.isCompleted;
        if (data.isCompleted && !widget.loop) {
          data.showControl = true;
        }
        data.notify();
      }
    });
  }

  @override
  void dispose() {
    data.controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return VisibilityDetector(
      key: ValueKey(widget.key),
      onVisibilityChanged: (info) {
        if (mounted) {
          if (info.visibleFraction < 1 && !data.isFullScreen) {
            isPlayingBeforeLeave = data.controller.value.isPlaying;
            data.controller.pause();
          } else if (info.visibleFraction == 1 && isPlayingBeforeLeave) {
            data.controller.play();
          }
        }
      },
      child: MultiProvider(
        providers: [
          ChangeNotifierProvider<UiVideoData>.value(
            value: data,
          ),
        ],
        child: ChangeNotifierProvider.value(
          value: data,
          child: UiVideoInterface(video: data, isLive: widget.isLive),
        ),
      ),
    );
  }
}

///播放器界面
class UiVideoInterface extends StatefulWidget {
  const UiVideoInterface({
    super.key,
    this.isFullScreen = false,
    this.isLive = false,
    required this.video,
  });

  final bool isFullScreen;
  final UiVideoData video;
  final bool isLive;

  @override
  State<UiVideoInterface> createState() => _UiVideoInterfaceState();
}

class _UiVideoInterfaceState extends State<UiVideoInterface> {
  bool seeking = false;

  Timer? autoHideTimer;
  @override
  void initState() {
    super.initState();
    autoHide();
  }

  @override
  void dispose() {
    autoHideTimer?.cancel();
    super.dispose();
  }

  void autoHide() async {
    if (widget.isFullScreen) {
      widget.video.showControl = false;
    }
    // await 2.delay();
    // setState(() {
    //   showControl = false;
    // });
    // autoHideTimer?.cancel();
    // autoHideTimer = Timer.periodic(const Duration(seconds: 3), (timer) {
    //   if (!seeking && showControl && mounted) {
    //     setState(() {
    //       showControl = false;
    //     });
    //   }
    // });
  }

  void togglePlay() {
    if (widget.video.controller.value.isPlaying) {
      widget.video.controller.pause();
    } else {
      widget.video.controller.play();
    }
  }

  void toggleFullScreen(context) async {
    widget.video.showControl = false;
    if (widget.isFullScreen) {
      widget.video.isFullScreen = false;

      SystemChrome.setPreferredOrientations([
        DeviceOrientation.portraitUp,
      ]);
      await 0.1.delay();
      if (Navigator.of(context).canPop()) {
        Navigator.of(context).pop();
      }
    } else {
      widget.video.isFullScreen = true;
      Navigator.push(
        context,
        PageRouteBuilder(
          opaque: false,
          pageBuilder: (_, __, ___) => ChangeNotifierProvider.value(
            value: widget.video,
            child: UiVideoFullScreen(
              video: widget.video,
              isLive: widget.isLive,
            ),
          ),
        ),
      );
    }
    widget.video.notify();
  }

  String formatDuration(Duration duration) {
    String hours = duration.inHours.toString().padLeft(2, '0');
    String minutes =
        duration.inMinutes.remainder(60).toString().padLeft(2, '0');
    String seconds =
        duration.inSeconds.remainder(60).toString().padLeft(2, '0');
    if (duration.inHours > 0) {
      return "$hours:$minutes:$seconds";
    } else {
      return "$minutes:$seconds";
    }
  }

  String get currentTime =>
      formatDuration(widget.video.controller.value.position);
  String get totalTime =>
      formatDuration(widget.video.controller.value.duration);

  seekToRelativePosition(Offset globalPosition) {
    final RenderBox box = context.findRenderObject() as RenderBox;
    final Offset tapPos = box.globalToLocal(globalPosition);
    final double relative = tapPos.dx / box.size.width;
    final Duration position = widget.video.controller.value.duration * relative;
    widget.video.controller.seekTo(position);
  }

  @override
  Widget build(BuildContext context) {
    var video = Provider.of<UiVideoData>(context);

    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: () {
        setState(() {
          widget.video.showControl = !widget.video.showControl;
        });
      },
      onDoubleTap: () {
        toggleFullScreen(context);
      },
      onHorizontalDragStart: (DragStartDetails details) {
        if (!widget.isLive) {
          setState(() {
            seeking = true;
          });
        }
      },
      onHorizontalDragUpdate: (details) {
        if (!widget.isLive) {
          widget.video.controller.pause();
          seekToRelativePosition(details.globalPosition);
        }
      },
      onHorizontalDragEnd: (details) {
        if (!widget.isLive) {
          setState(() {
            seeking = false;
          });
          widget.video.controller.play();
        }
      },
      child: Stack(
        children: [
          Container(
            color: Colors.black,
            constraints: const BoxConstraints(minHeight: 100),
            child: Center(
              child: widget.video.controller.value.isInitialized
                  ? AspectRatio(
                      aspectRatio: widget.video.controller.value.aspectRatio,
                      child: VideoPlayer(widget.video.controller),
                    )
                  : Container(
                      padding: const EdgeInsets.all(20),
                      decoration: BoxDecoration(
                        color: Colors.grey.withOpacity(0.2),
                        borderRadius: BorderRadius.circular(10),
                      ),
                      child: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          widget.video.isError
                              ? const Icon(Icons.error,
                                  size: 40, color: Colors.white70)
                              : const CupertinoActivityIndicator(
                                  color: Colors.white70,
                                  radius: 12,
                                ),
                          const SizedBox(height: 10),
                          Text(
                            widget.video.isError ? '视频加载失败' : '视频加载中',
                            style: const TextStyle(fontSize: 12),
                          ),
                        ],
                      ),
                    ),
            ),
          ),
          if (widget.video.showPlayButton &&
              widget.video.controller.value.isInitialized)
            Positioned.fill(
              child: Center(
                child: UiTap(
                  onTap: () {
                    widget.video.controller.play();
                  },
                  child: CircleAvatar(
                    backgroundColor: Colors.white.withOpacity(0.8),
                    child: Icon(
                      Icons.play_arrow,
                      color: Colors.black.withOpacity(0.9),
                    ),
                  ),
                ),
              ),
            ),
          if (widget.isFullScreen && widget.video.showControl)
            Positioned(
              top: 0,
              left: 0,
              right: 0,
              child: Container(
                padding: const EdgeInsets.only(bottom: 10),
                decoration: BoxDecoration(
                  gradient: LinearGradient(
                    begin: Alignment.bottomCenter,
                    end: Alignment.topCenter,
                    colors: [
                      Colors.transparent,
                      Colors.black.withOpacity(0.7),
                    ],
                  ),
                ),
                child: AppBar(
                  foregroundColor: Colors.white,
                  leading: BackButton(
                    onPressed: () {
                      toggleFullScreen(context);
                    },
                  ),
                  elevation: 0.5,
                  titleSpacing: 0,
                  backgroundColor: Colors.transparent,
                  toolbarHeight: 40,
                  title: Text(
                    widget.video.title ?? '',
                    style: const TextStyle(
                      fontSize: 16,
                      fontWeight: FontWeight.normal,
                      color: Colors.white,
                    ),
                  ),
                ),
              ),
            ),
          if (seeking)
            Align(
              alignment: Alignment.center,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Container(
                    height: widget.isFullScreen ? 60 : 40,
                    padding: const EdgeInsets.symmetric(horizontal: 10),
                    constraints: BoxConstraints(
                      minWidth: widget.isFullScreen ? 220 : 150,
                    ),
                    decoration: BoxDecoration(
                      color: Colors.black.withOpacity(0.3),
                      borderRadius: BorderRadius.circular(5),
                    ),
                    child: Center(
                      child: Text(
                        '$currentTime / $totalTime',
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: widget.isFullScreen ? 30 : 20,
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          if (widget.video.controller.value.isInitialized &&
              (widget.video.showControl || seeking))
            Positioned(
              bottom: 0,
              left: 0,
              right: 0,
              child: Container(
                decoration: BoxDecoration(
                  gradient: LinearGradient(
                    begin: Alignment.topCenter,
                    end: Alignment.bottomCenter,
                    colors: [
                      Colors.transparent,
                      Colors.black.withOpacity(0.7),
                    ],
                  ),
                ),
                child: SafeArea(
                    bottom: false,
                    child: DefaultTextStyle(
                      style: const TextStyle(
                        color: Colors.white,
                        fontSize: 12,
                      ),
                      child: Row(
                        children: [
                          IconButton(
                            onPressed: togglePlay,
                            icon: Icon(
                              widget.video.controller.value.isPlaying
                                  ? Icons.pause
                                  : Icons.play_arrow,
                              color: Colors.white,
                            ),
                          ),
                          Text(currentTime),
                          const SizedBox(width: 15),
                          Expanded(child: progressBar(video.progress)),
                          const SizedBox(width: 15),
                          Text(widget.isLive ? "LIVE" : totalTime),
                          IconButton(
                            onPressed: () {
                              toggleFullScreen(context);
                            },
                            icon: Icon(
                              widget.isFullScreen
                                  ? Icons.fullscreen_exit
                                  : Icons.fullscreen,
                              color: Colors.white,
                            ),
                          ),
                        ],
                      ),
                    )),
              ),
            )
        ],
      ),
    );
  }

  Widget progressBar(progress) {
    return widget.isLive
        ? Container()
        : LinearProgressIndicator(
            value: progress,
            color: Colors.white,
            backgroundColor: Colors.grey.withOpacity(0.3),
          );
  }
}

/// 全屏播放
class UiVideoFullScreen extends StatefulWidget {
  final UiVideoData video;
  final bool isLive;
  const UiVideoFullScreen({
    super.key,
    required this.video,
    this.isLive = false,
  });

  @override
  _UiVideoFullScreenState createState() => _UiVideoFullScreenState();
}

class _UiVideoFullScreenState extends State<UiVideoFullScreen> {
  @override
  void initState() {
    super.initState();
    requestFullScreen();
  }

  @override
  void dispose() {
    exitFullScreen();
    super.dispose();
  }

  requestFullScreen() async {
    if (mounted) {
      SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
      SystemChrome.setPreferredOrientations([
        Platform.isAndroid
            ? DeviceOrientation.landscapeLeft
            : DeviceOrientation.landscapeRight,
      ]);
    }
  }

  void exitFullScreen() async {
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
    ]);
    SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: UiVideoInterface(
        isFullScreen: true,
        isLive: widget.isLive,
        video: widget.video,
      ),
    );
  }
}
